//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<InputReflection.cpp>
///	@path	~/src/appear/xwin/
///	@date	2007/11/08
///	@desc	Reflects inputs to engine's event center.

#include "config/config.h"

#include "lib/utilities/observer.h"

#include "appear/xwin/InputReflection.h"

#include "engine/xcore/event_center.h"

namespace xeres {

	// ctor
	InputReflection::InputReflection( void )
	{
	}

	// dtor
	InputReflection::~InputReflection( void )
	{
	}

	// on key input
	HandleInput InputReflection::OnKeyInput( const KeyInput& input )
	{
		_InputMessage iBuffer;
		memset( &iBuffer , 0 , sizeof(_InputMessage) );
		memcpy( &iBuffer , &input , sizeof(KeyInput) );
		m_messageQueue.push_back( iBuffer );
		return INPUT_HANDLED;
	}

	// on mouse input
	HandleInput InputReflection::OnMouseInput( const MouseInput& input )
	{
		_InputMessage iBuffer;
		memset( &iBuffer , 0 , sizeof(_InputMessage) );
		memcpy( &iBuffer , &input , sizeof(MouseInput) );
		m_messageQueue.push_back( iBuffer );
		return INPUT_HANDLED;
	}

	// register input callback
	bool InputReflection::ConnectEngine( Engine& engine )
	{
		if( m_keyEvent.IsValid() || m_mouseEvent.IsValid() )
			return false;

		m_keyEvent = new CInputEvent;
		m_mouseEvent = new CInputEvent;

		engine.RegisterEvent( _S("input/keyboard") , m_keyEvent , false );
		engine.RegisterEvent( _S("input/mouse") , m_mouseEvent , false );

		if( !engine.InsertStage( _S("input/input") , _S("") , bind( &InputReflection::DispatchInput , this ) ) )
		{
			return false;
		}
		return true;
	}

	// dispatch input
	void InputReflection::DispatchInput( void )
	{
		COUNTER_GUARD( _S("dispatch_input") );
		// for all inputs
		if( !m_messageQueue.empty() )
		{
			for( size_t i = 0 , total = m_messageQueue.size() ; i < total ; ++i )
			{
				Input * pInput = (Input*)( m_messageQueue[i].buffer );
				if( pInput->GetType() == Input::TYPE_KEY )
				{
					m_keyEvent->Active( pInput );
				}
				else if( pInput->GetType() == Input::TYPE_MOUSE )
				{
					m_mouseEvent->Active( pInput );
				}
				else
				{
					assert(false);
				}
			}
			m_messageQueue.clear();
		}
	}

} // namespace xeres
